package cc.eguid.tools.ui;

import cc.eguid.tools.FileTransferClient;
import cc.eguid.tools.LocalClient;
import cc.eguid.tools.common.InstructionEnum;
import cc.eguid.tools.msg.InstructionMessage;
import com.alibaba.fastjson.JSONObject;

import javax.swing.*;
import java.awt.*;
import java.awt.event.HierarchyEvent;
import java.io.File;
import java.io.IOException;
import java.util.Objects;

/**
 * 客户端面板
 */
public class ClientPanel extends JPanel {
    private JTextField ipField, portField, filePortField;
    private JButton connectButton, disconnectButton;
    private JLabel statusLabel;
    private RemoteDesktop remoteDesktop;
    private LocalClient client;
    private Thread clientThread;

    private JTextField tokenField;//令牌字段

    private JSpinner qualityField;//图像质量数字调节

    private JButton uploadButton;//上传按钮

    private JTextField uploadPathField;//上传路径

    public ClientPanel() {
        setLayout(new BorderLayout());

        // 顶部控制面板
        JPanel controlPanel = new JPanel(new FlowLayout());
        controlPanel.add(new JLabel("IP:"));
        ipField = new JTextField("127.0.0.1", 8);
        controlPanel.add(ipField);

        controlPanel.add(new JLabel("远程端口:"));
        portField = new JTextField(String.valueOf(RemoteAssistance.DEFAULT_PORT), 3);
        controlPanel.add(portField);

        controlPanel.add(new JLabel("文件端口:"));
        filePortField = new JTextField(String.valueOf(RemoteAssistance.DEFAULT_FILE_TRANSFER_PORT), 3);
        controlPanel.add(filePortField);

        connectButton = new JButton("\uD83D\uDD17 连接");
        disconnectButton = new JButton("\uD83D\uDD0C 断开");
        disconnectButton.setEnabled(false);

        controlPanel.add(connectButton);
        controlPanel.add(disconnectButton);

        statusLabel = new JLabel("\uD83D\uDD34 未连接");
        controlPanel.add(statusLabel);

        add(controlPanel, BorderLayout.NORTH);

        // 远程桌面显示区域
        remoteDesktop = new RemoteDesktop();
        add(remoteDesktop, BorderLayout.CENTER);
        // 容器显示后确保远程桌面获取焦点
        remoteDesktop.addHierarchyListener(e -> {
            if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && remoteDesktop.isShowing()) {
                SwingUtilities.invokeLater(remoteDesktop::requestFocusInWindow);
            }
        });

        // 事件监听
        connectButton.addActionListener(e -> connect());
        disconnectButton.addActionListener(e -> disconnect());

        //令牌
        controlPanel.add(new JLabel("令牌:"));
        tokenField = new JTextField("000000", 6);
        controlPanel.add(tokenField);

        //图像质量
        controlPanel.add(new JLabel("图像质量:"));
        SpinnerNumberModel decimalModel = new SpinnerNumberModel(1.0, 0.0, 1.0, 0.1);
        qualityField = new JSpinner(decimalModel);
        qualityField.addChangeListener(e -> changeQuality());
        controlPanel.add(qualityField);

        JPanel controlPanel2 = new JPanel(new FlowLayout());
        //添加上传功能
        controlPanel2.add(new JLabel("上传路径:"));
        uploadPathField = new JTextField(System.getProperty("user.home") + File.separator + "uploads", 15);
        controlPanel2.add(uploadPathField);

        uploadButton = new JButton("\uD83D\uDCE4 上传文件");
        uploadButton.setEnabled(false);
        controlPanel2.add(uploadButton);
        add(controlPanel2, BorderLayout.SOUTH);
        //上传事件监听部分添加
        uploadButton.addActionListener(e -> uploadFile());

    }

    private void changeQuality() {
        Double newQuality = (double) qualityField.getValue();

        if (newQuality!=null&&checkNumRange(newQuality,0L,1L)) {
            if (Objects.nonNull(client) && newQuality != client.getImageQuality()) {
                client.setImageQuality(newQuality);
                JSONObject qualityJson = new JSONObject();
                qualityJson.put("quality", newQuality);
                InstructionMessage instructionMessage = new InstructionMessage(InstructionEnum.IMAGE_QUALITY, qualityJson);
                client.sendInstructionMessage(instructionMessage);
            }
            // Do nothing
        }else{
            JOptionPane.showMessageDialog(this, "图像质量范围只能设置0到1之间的小数（含0和1）");
        }
    }

    private boolean checkNumRange(double num,double min,double max){
        return num>=min&&num<=max;
    }

    private void connect() {
        try {
            String ip = ipField.getText();
            int port = Integer.parseInt(portField.getText());
            String token = tokenField.getText().trim();
            Double quality=(double)qualityField.getValue();
            // 验证令牌格式
            if (!token.matches("\\d{6}")) {
                JOptionPane.showMessageDialog(this, "令牌必须是6位数字", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }

            // 先清理旧连接（如果存在）
            if (client != null) {
                client.disconnect();
                client = null;
            }

            // 等待旧线程结束
            if (clientThread != null && clientThread.isAlive()) {
                try {
                    clientThread.join(1000); // 等待最多1秒
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                clientThread = null;
            }

            // 先设置UI状态为连接中
            connectButton.setEnabled(false);
            disconnectButton.setEnabled(true);
            uploadButton.setEnabled(false); // 连接中时禁用上传按钮
            statusLabel.setText("连接中...");

            client = new LocalClient(ip, port, token, remoteDesktop, this,quality);
            clientThread = new Thread(client, "eguid-LocalClient");
            clientThread.setDaemon(true);
            clientThread.start();

        } catch (Exception ex) {
            JOptionPane.showMessageDialog(this, "连接失败: " + ex.getMessage());
            // 连接异常时重置UI状态
            onConnectionFailed();
        }
    }

    private void disconnect() {
        if (client != null) {
            client.disconnect();
            client = null;
        }

        // 等待线程结束
        if (clientThread != null && clientThread.isAlive()) {
            try {
                clientThread.join(1000); // 等待最多1秒
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            clientThread = null;
        }

        connectButton.setEnabled(true);
        disconnectButton.setEnabled(false);
        uploadButton.setEnabled(false); // 断开连接后禁用上传按钮
        statusLabel.setText("已断开连接");
    }

    // 连接成功时调用
    public void onConnectionSuccess() {
        SwingUtilities.invokeLater(() -> {
            uploadButton.setEnabled(true); // 连接成功后启用上传按钮
            statusLabel.setText("已连接");
            remoteDesktop.requestFocusInWindow();
        });
    }

    // 连接失败时调用
    public void onConnectionFailed() {
        SwingUtilities.invokeLater(() -> {
            connectButton.setEnabled(true);
            disconnectButton.setEnabled(false);
            uploadButton.setEnabled(false);
            statusLabel.setText("连接失败");
        });
    }


    // 添加上传文件方法
    private void uploadFile() {
        if (client == null || !client.isConnected()) {
            JOptionPane.showMessageDialog(this, "未连接到服务端", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setDialogTitle("选择要上传的文件");
        fileChooser.setMultiSelectionEnabled(false);

        int result = fileChooser.showOpenDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {
            File selectedFile = fileChooser.getSelectedFile();
            String targetPath = uploadPathField.getText().trim();

            if (targetPath.isEmpty()) {
                JOptionPane.showMessageDialog(this, "请指定上传路径", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }

            // 在新线程中执行文件上传，避免阻塞UI
            new Thread(() -> {
                try {
                    String ip = ipField.getText();
                    int filePort = Integer.parseInt(filePortField.getText());
                    String token = tokenField.getText().trim();
                    // 使用独立的文件传输客户端
                    FileTransferClient fileClient = new FileTransferClient(ip, filePort, token);
                    fileClient.uploadFile(selectedFile, targetPath);

                    SwingUtilities.invokeLater(() ->
                            JOptionPane.showMessageDialog(this,
                                    "文件上传成功: " + selectedFile.getName(),
                                    "上传成功", JOptionPane.INFORMATION_MESSAGE)
                    );
                } catch (IOException e) {
                    SwingUtilities.invokeLater(() ->
                            JOptionPane.showMessageDialog(this,
                                    "文件上传失败: " + e.getMessage(),
                                    "上传失败", JOptionPane.ERROR_MESSAGE)
                    );
                }
            }).start();
        }
    }
}
